﻿using System;
using System.Data;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using System.Text;

/// <summary>
/// Template 的摘要说明
/// </summary>
public class Template
{
    public Template()
    {
        //
        // TODO: 在此处添加构造函数逻辑
        //
    }

    //字段
    private int _id;       //id
    private int _cid;      //栏目id
    private string _paramter = "";

    private string _contentSql = "";
    private string _sqlstr = "";     //sql语句
    private string _sqlid;         //组sqlID
    private string _template;      //模板标签
    private string _subdltag = "";
    private string _templateblock; //模板块
    private string _contentblock;  //内容块



    //分页

    private string _pagesql = "";
    private int _pagesize;
    private int _totalrecord;     //总记录数
    private int _pagecount = 0;     //页数
    private string _pagefileformat = "";
    private string _pageblock;     //page标签块
    private string _pagecontentblock; //内容块
    private int _currentpage = 1;  //当前页
    private string _pageorderid;


    //条件语句

    private string _ifblock;
    private string _ifstr;
    private string _successstr;
    private string _failurestr;
    private string _typestr;
    private string _leftstr;
    private string _rightstr;
    private string _opifstr;


    //解析标签
    private string _Analysisblock;
    private string _Analysis;
    private string _Analysistag;
    private string _Analysisformat;



    /// <summary>
    /// 内容ID
    /// </summary>
    public int id
    {
        set { _id = value; }
        get { return _id; }
    }

    /// <summary>
    /// 栏目ID
    /// </summary>
    public int cid
    {
        set { _cid = value; }
        get { return _cid; }
    }

    public string paramter
    {
        set { _paramter = value; }
        get { return _paramter; }
    }

    /// <summary>
    /// 默认sqlstr
    /// </summary>
    public string sqlstr
    {
        set { _sqlstr = value; }
        get { return _sqlstr; }
    }

    public string sqlid
    {
        set { _sqlid = value; }
        get { return _sqlid; }
    }

    public string template
    {
        set { _template = value; }
        get { return _template; }
    }


    public string contentSql
    {
        set { _contentSql = value; }
        get { return _contentSql; }
    }

    public int currentpage
    {
        set { _currentpage = value; }
        get { return _currentpage; }
    }
    public int pagecount
    {
        set { _pagecount = value; }
        get { return _pagecount; }
    }



    public string pagefileformat
    {
        set { _pagefileformat = value; }
        get { return _pagefileformat; }
    }



    //条件

    public string leftstr
    {
        set { _leftstr = value; }
        get { return _leftstr; }
    }

    public string rightstr
    {
        set { _rightstr = value; }
        get { return _rightstr; }
    }


    public string typestr
    {
        set { _typestr = value; }
        get { return _typestr; }
    }
    public string opifstr
    {
        set { _opifstr = value; }
        get { return _opifstr; }
    }

    public string failurestr
    {
        set { _failurestr = value; }
        get { return _failurestr; }
    }

    public string successstr
    {
        set { _successstr = value; }
        get { return _successstr; }
    }



    //---------------匹配标签----------------------------

    //通用标签{dl}{/dl}
    //子标签：循环标签{tag:sql }{/tag},字段:包含常量字段，变量字段，数据库字段[field format:xxxx len=9],判断标签If 条件 结果
    //{dl}
    //{tag:sql sql}
    //[field type=xxx format=xxx len=] ,If[[field type=xxx format=xxx len=]] 结果1|结果2
    //{/tag}
    //{/dl}


    //public string   GetOutTag()
    //{
    //    string _tmp = _template;
    //    Regex re = new Regex(string.Format(@"{0}(?>{0}(?<LEVEL>)|{1}(?<-LEVEL>)|(?!{0}|{1}).)+(?(LEVEL)(?!)){1}", "{dl}", "{/dl}"), RegexOptions.IgnoreCase);
    //    //Match m=re.Match(_templatestr);

    //    MatchCollection mc = re.Matches(_tmp);
    //    foreach (Match m in mc)
    //    {
    //        _subdltag = m.Value;
    //        _tmp = _tmp.Replace(m.Value, getChangeContent());
    //    }
    //    return _tmp;

    //}
    public void GetAllLoop()
    {
        GetSigleContent();
        while (_template.IndexOf("{loop") > 0)
        {
            GetsubTag2();
        }

        GetPageTag();
        GetPageParamter();
        GetPageUrlContent();
        // GetPageContent();
    }



    /// <summary>
    /// 取一组标签sqlid名称
    /// </summary>
    /// <param name="_templatestr"></param>
    /// <returns></returns>
    public void GetsubTag2()
    {
        string _tmp = "";

        Regex re = new Regex(@"{loop:(\w+)[\s\S]+?}([\s\S]+){/loop:\1}", RegexOptions.IgnoreCase);
        MatchCollection mc = re.Matches(_template);
        foreach (Match m in mc)
        {
            _tmp = m.Groups[1].Value;
            this._sqlid = _tmp;
            this._templateblock = m.Groups[0].Value;
            this._contentblock = m.Groups[2].Value;
            _template = _template.Replace(m.Value, getChangeContent());
        }

    }
    /// <summary>
    /// 取一组标签sqlid名称
    /// </summary>
    /// <param name="_templatestr"></param>
    /// <returns></returns>
    private void GetsubTag()
    {
        string _tmp = "";
        Regex re = new Regex(@"{loop:(\w+)[\s\S]+}([\s\S]+){/loop:\1}", RegexOptions.IgnoreCase);
        Match m = re.Match(_subdltag);
        _tmp = m.Groups[1].Value;
        this._sqlid = _tmp;
        this._templateblock = m.Groups[0].Value;
        this._contentblock = m.Groups[2].Value;
    }

    /// <summary>
    /// 取SQL参数
    /// </summary>
    /// <param name="_templatestr"></param>
    /// <returns></returns>
    private string GetSqlParamter()
    {
        // GetsubTag();
        string pat = Convert.ToString("{loop:" + this._sqlid + @" ([\s\S]+?)}");
        Regex re = new Regex(pat, RegexOptions.IgnoreCase);
        Match m = re.Match(_templateblock);
        return m.Groups[1].Value;

    }






    /// <summary>
    /// 拼结SQL
    /// </summary>
    /// <param name="_templatestr"></param>
    /// <returns></returns>
    private void GetSQLString()
    {
        string _sql = GetSqlParamter();

        _sql = _sql.Replace("$$id", _id.ToString());
        _sql = _sql.Replace("$$cid", _cid.ToString());
        _sql = _sql.Replace("$$paramter", _paramter);
        _sql = GetOneofGropvalue(@"sqlstr=#([\s\S]*?)#", _sql, 1);
        this._sqlstr = _sql;

    }


    //{dl:field type="title" width="100"}{/dl:field}{dl:field type="desction" width="100"}{/dl:field}

    /// <summary>
    /// 取得内容
    /// </summary>
    /// <param name="regstr"></param>
    /// <returns></returns>
    private string GetContent(IDataReader dr)
    {
        string _tmpstr = "";
        _tmpstr = _contentblock;
        Regex reg = new Regex(@"\[field:" + _sqlid + @" ([\s\S]+?)\]", RegexOptions.IgnoreCase);
        MatchCollection mc = reg.Matches(_tmpstr);
        for (int i = 0; i < mc.Count; i++)
        {
            _tmpstr = _tmpstr.Replace(mc[i].Value.ToString(), GetField(mc[i].Value.ToString(), dr));
        }
        return _tmpstr;

    }

    /// <summary>
    /// 取得PageUrl内容
    /// </summary>
    /// <param name="regstr"></param>
    /// <returns></returns>
    public void GetPageUrlContent()
    {

        Regex reg = new Regex(@"\[pageurl ([\s\S]+?)\]", RegexOptions.IgnoreCase);
        MatchCollection mc = reg.Matches(_template);
        for (int i = 0; i < mc.Count; i++)
        {
            GetPageurlField(mc[i].Value.ToString());
        }

    }

    private void GetPageurlField(string Pageurl)
    {
        if (_pagefileformat != "")
        {
            string _filetemp = GetOneofGropvalue(@"type=#([\s\S]+)#", Pageurl, 1);

            switch (_filetemp)
            {
                case "first":
                    _template = _template.Replace(Pageurl, _pagefileformat.Replace("#page#", "1"));
                    break;
                case "previous":
                    if (currentpage == 1)
                    {
                        _template = _template.Replace(Pageurl, _pagefileformat.Replace("#page#", "1"));
                    }
                    else
                    {
                        _template = _template.Replace(Pageurl, _pagefileformat.Replace("#page#", Convert.ToString(_currentpage - 1)));
                    }
                    break;
                case "next":
                    if (pagecount > 1)
                    {
                        if (_currentpage == pagecount)
                            _template = _template.Replace(Pageurl, _pagefileformat.Replace("#page#", Convert.ToString(_currentpage)));
                        else
                            _template = _template.Replace(Pageurl, _pagefileformat.Replace("#page#", Convert.ToString(_currentpage + 1)));

                    }
                    else
                    {
                        _template = _template.Replace(Pageurl, _pagefileformat.Replace("#page#", "1"));

                    }
                    break;
                case "last":
                    _template = _template.Replace(Pageurl, _pagefileformat.Replace("#page#", _pagecount.ToString()));
                    break;



            }
        }

    }

    /// <summary>
    /// 替换单页内容标签
    /// </summary>
    /// <param name="dr"></param>
    /// <returns></returns>
    private void GetSigleContent(IDataReader dr)
    {

        Regex reg = new Regex(@"\[sfield ([\s\S]+?)\]", RegexOptions.IgnoreCase);
        MatchCollection mc = reg.Matches(_template);
        for (int i = 0; i < mc.Count; i++)
        {
            _template = _template.Replace(mc[i].Value.ToString(), GetField(mc[i].Value.ToString(), dr));
        }


    }

    private void GetPageUrl()
    {

    }



    /// <summary>
    /// 替换分页内容
    /// </summary>
    /// <param name="dr"></param>
    /// <returns></returns>
    private string GetPageContent(IDataReader dr)
    {
        string _temp = _pagecontentblock;
        Regex reg = new Regex(@"\[pfield ([\s\S]+?)\]", RegexOptions.IgnoreCase);
        MatchCollection mc = reg.Matches(_pagecontentblock);
        for (int i = 0; i < mc.Count; i++)
        {
            _temp = _pagecontentblock.Replace(mc[i].Value.ToString(), GetField(mc[i].Value.ToString(), dr));
        }

        return _temp;
    }
    //{dl:field type="title" width="100" format="1,2,3"}{/dl:field}
    /// <summary>
    /// 取得字段值
    /// </summary>
    /// <param name="regstr"></param>
    /// <param name="dr"></param>
    /// <returns></returns>
    private string GetField(string _content, IDataReader dr)
    {

        string _field = "";
        string _format = "";
        string _width = "";

        _field = GetOneofGropvalue(@"type=#([\s\S]+?)#", _content, 1).Trim();
        _format = GetOneofGropvalue(@"format=#([\s\S]+?)#", _content, 1).Trim();
        _width = GetOneofGropvalue(@"width=#([\s\S]+?)#", _content, 1).Trim();

        if (_field.Trim() == "")
        {
            return "";
        }
        else
        {
            string temp = dr[_field.Trim()].ToString();
            if (_format != "")
            {
                temp = string.Format("{" + _format + "}", temp);
            }
            if (_width != "")
            {
                temp = Sub(temp, Convert.ToInt32(_width));
            }
            return temp;
        }


    }



    /// <summary>
    /// 取得单循环内容
    /// </summary>
    /// <returns></returns>
    public string getChangeContent()
    {
        GetSQLString();

        SqlDataReader dr = DbHelperSQL.ExecuteReader(_sqlstr);
        string _tmp = "";
        if (dr.HasRows)
        {
            int i = 1;
            while (dr.Read())
            {
                _tmp += GetContent(dr).Replace("[#num#]", i.ToString());
                i++;
            }
        }
        dr.Close();
        return _tmp;
    }

    public void GetPageContent()
    {
        if (_pagecount > 0)
        {
            string _temp = "";
            string _tmpsqlstr = "";
            if (_currentpage == 1)
            {
                _tmpsqlstr = "select top " + _pagesize + " " + GetOneofGropvalue(@"select([\s\S]+)", _pagesql, 1);
            }
            else
            {
                _tmpsqlstr = "select top " + _pagesize + " " + GetOneofGropvalue(@"select([\s\S]+) order ", _pagesql, 1) + " where  " + _pageorderid + " not in(select top " + (_currentpage - 1) * _pagesize + "  " + _pageorderid + " from " + GetOneofGropvalue(@"from([\s\S]+)", _pagesql, 1) + ")" + GetOneofGropvalue(@" order ([\s\S]+)", _pagesql, 0);
            }
            SqlDataReader dr = DbHelperSQL.ExecuteReader(_tmpsqlstr);
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    _temp += GetPageContent(dr);
                }
            }

            dr.Close();
            _template = _template.Replace(_pageblock, _temp);
            //_template = _tmpsqlstr;
        }
    }

    /// <summary>
    /// 取得单页dr
    /// </summary>
    private void GetSigleContent()
    {
        if (_contentSql != "")
        {
            SqlDataReader dr = DbHelperSQL.ExecuteReader(_contentSql);
            // string _tmp = "";
            if (dr.HasRows)
            {
                while (dr.Read())
                {
                    GetSigleContent(dr);
                }
            }
            dr.Close();
        }
    }



    /// <summary>
    /// 取得分页参数
    /// </summary>
    private void GetPageTag()
    {
        Regex re = new Regex(@"{page ([\s\S]+?)}([\s\S]+?){/page}", RegexOptions.IgnoreCase);
        Match m = re.Match(_template);
        if (m.Success)
        {

            _pagesql = GetOneofGropvalue(@"sqlstr=#([\s\S]*?)#", m.Groups[1].Value, 1);
            _pagesql = _pagesql.Replace("$$id", _id.ToString());
            _pagesql = _pagesql.Replace("$$cid", _cid.ToString());
            _pagesql = _pagesql.Replace("$$paramter", _paramter);
            _pageorderid = GetOneofGropvalue(@"order by ([\s\S]+)(asc|desc)", _pagesql, 1).Trim();
            _pagesize = Convert.ToInt32(GetOneofGropvalue(@"pagesize=#([\s\S]*?)#", m.Groups[1].Value, 1));
            _pageblock = m.Value;
            _pagecontentblock = m.Groups[2].Value;

        }

    }


    /// <summary>
    /// 取得分页参数II
    /// </summary>
    private void GetPageParamter()
    {
        if (_pagesql != "")
        {
            string _tmpsql = "";
            if (_pagesql.IndexOf(',') > 0)
            {
                _tmpsql = "select count(" + GetOneofGropvalue(@"select ([\s\S]+?),[\s\S]+? from ([\s\S]+)", _pagesql, 1).Trim() + ") from" + GetOneofGropvalue(@"select ([\s\S]+) from ([\s\S]+)", _pagesql, 2);
            }
            else
            {
                _tmpsql = "select count(" + GetOneofGropvalue(@"select ([\s\S]+?)from ([\s\S]+)", _pagesql, 1).Trim() + ")  from" + GetOneofGropvalue(@"select ([\s\S]+) from ([\s\S]+)", _pagesql, 2);

            }
            if (_tmpsql.IndexOf(" order ") > 0)
                _tmpsql = GetOneofGropvalue(@"([\s\S]+) order ", _tmpsql, 1);

            _totalrecord = Convert.ToInt32(DbHelperSQL.GetSingle(_tmpsql));

            if (_totalrecord > 0)
            {
                _pagecount = Convert.ToInt32(Math.Ceiling((decimal)_totalrecord / _pagesize));
            }
            else
            {
                _pagecount = 0;
            }
        }
    }

    //-----------------------IF条件---------------------------
    /// <summary>
    /// 替换选择标签IF
    /// </summary>
    public void getAllIfTag()
    {
        Regex reg = new Regex(@"{if ([\s\S]+?)}([\s\S]+?){else}([\s\S]+?){/if}", RegexOptions.IgnoreCase);
        MatchCollection mc = reg.Matches(_template);
        for (int i = 0; i < mc.Count; i++)
        {
            getifresult(mc[i].Value.ToString());
        }
    }


    private bool GetIfParamter(string str)
    {
        _ifblock = GetOneofGropvalue(@"{if ([\s\S]+?)}([\s\S]+?){else}([\s\S]+?){/if}", str, 0);
        _ifstr = GetOneofGropvalue(@"{if ([\s\S]+?)}([\s\S]+?){else}([\s\S]+?){/if}", str, 1);
        _successstr = GetOneofGropvalue(@"{if ([\s\S]+?)}([\s\S]+?){else}([\s\S]+?){/if}", str, 2);
        _failurestr = GetOneofGropvalue(@"{if ([\s\S]+?)}([\s\S]+?){else}([\s\S]+?){/if}", str, 3);

        _typestr = GetOneofGropvalue(@"([\s\S]+):", _ifstr, 1);
        _leftstr = GetOneofGropvalue(_typestr + @":([\s\S]+)(>|<|>=|<=|!=|==)", _ifstr, 1);
        _rightstr = GetOneofGropvalue(@"(>|<|>=|<=|!=|==)([\s\S]+)", _ifstr, 2);

        if (_leftstr.IndexOf("len(") > -1)
        {
            _leftstr = GetOneofGropvalue(@"len\(([\s\S]+)\)", _leftstr, 1).Length.ToString();
        }
        _opifstr = GetOneofGropvalue(_typestr + @":([\s\S]+)(>|<|>=|<=|!=|==)", _ifstr, 2);
        bool getbool = false;

        if (_opifstr == ">")
        {
            if (_typestr == "int")
            {
                getbool = (Convert.ToInt32(_leftstr) > Convert.ToInt32(_rightstr));
                return getbool;
            }
            if (_typestr == "datetime")
            {
                return (Convert.ToDateTime(_leftstr) > Convert.ToDateTime(_rightstr));
            }
        }

        if (_opifstr == "<")
        {
            if (_typestr == "int")
            {
                return (Convert.ToInt32(_leftstr) < Convert.ToInt32(_rightstr));
            }
            if (_typestr == "datetime")
            {
                return (Convert.ToDateTime(_leftstr) < Convert.ToDateTime(_rightstr));
            }
        }
        if (_opifstr == ">=")
        {
            if (_typestr == "int")
            {
                return (Convert.ToInt32(_leftstr) >= Convert.ToInt32(_rightstr));
            }
            if (_typestr == "datetime")
            {
                return (Convert.ToDateTime(_leftstr) >= Convert.ToDateTime(_rightstr));
            }
        }
        if (_opifstr == "<=")
        {
            if (_typestr == "int")
            {
                return (Convert.ToInt32(_leftstr) <= Convert.ToInt32(_rightstr));
            }
            if (_typestr == "datetime")
            {
                return (Convert.ToDateTime(_leftstr) <= Convert.ToDateTime(_rightstr));
            }
        }
        if (_opifstr == "==")
        {
            if (_typestr == "string")
            {
                return (Convert.ToString(_leftstr) == Convert.ToString(_rightstr));
            }
            if (_typestr == "int")
            {
                return (Convert.ToInt32(_leftstr) == Convert.ToInt32(_rightstr));
            }
            if (_typestr == "datetime")
            {
                return (Convert.ToDateTime(_leftstr) == Convert.ToDateTime(_rightstr));

            }
        }
        if (_opifstr == "!=")
        {
            if (_typestr == "string")
            {
                return (Convert.ToString(_leftstr) != Convert.ToString(_rightstr));
            }
            if (_typestr == "int")
            {
                return (Convert.ToInt32(_leftstr) != Convert.ToInt32(_rightstr));
            }
            if (_typestr == "datetime")
            {
                return (Convert.ToDateTime(_leftstr) != Convert.ToDateTime(_rightstr));
            }
        }

        return false;
    }

    /// <summary>
    /// 取得IF结果
    /// </summary>
    /// <param name="str"></param>
    public void getifresult(string str)
    {

        if (GetIfParamter(str))
        {
            _template = _template.Replace(_ifblock, _successstr);
        }
        else
        {
            _template = _template.Replace(_ifblock, _failurestr);
        }
    }



    //------------------------------------解析内容标签-------------------------------------------------
    //{reg text=## pattern=##}{/reg}
    private void GetAnalysisParamter()
    {

        _Analysis = GetOneofGropvalue(@"{reg text=#([\s\S]*?)# pattern=#([\s\S]*?)#}", _Analysisblock, 1);
        _Analysistag = GetOneofGropvalue(@"{reg text=#([\s\S]*?)# pattern=#([\s\S]*?)#}", _Analysisblock, 2);
        _Analysisformat = GetOneofGropvalue(@"{reg text=#([\s\S]*?)# pattern=#([\s\S]*?)#}([\s\S]*){/reg}", _Analysisblock, 3);
    }

    private string GetAnalysisValue()
    {
        string _sigletemp = "";
        if (_Analysistag != "" && _Analysis != "")
        {


            Regex re = new Regex(_Analysistag);
            MatchCollection mc = re.Matches(_Analysis);
            foreach (Match m in mc)
            {
                string _temp = _Analysisformat;
                for (int i = 0; i < m.Groups.Count; i++)
                {
                    _temp = _temp.Replace("{" + i + "}", m.Groups[i].ToString());
                }
                _sigletemp += _temp;
            }
        }
        return _sigletemp;
    }


    public void GetAllAnalysisValue()
    {
        Regex re = new Regex(@"{reg [\s\S]+?{/reg}");
        MatchCollection mc = re.Matches(_template);
        foreach (Match m in mc)
        {
            this._Analysisblock = m.Value;
            GetAnalysisParamter();
            _template = _template.Replace(_Analysisblock, GetAnalysisValue());
        }
    }

    //---------------------------------------------------------------------------------------

    //-------------------------------------------------
    //子标签-------------------------
    //SQL循环标签
    //分页标签
    //导航标签

    //条件标签

    //子标签-------------------------


    //{dl}
    //{tag:sql}
    //[field type=xx format=xxx len=9]
    //{/tag:sql}
    //{/dl}

    /// <summary>
    /// 截取字符串
    /// </summary>
    /// <param name="strTitle"></param>
    /// <param name="length"></param>
    /// <returns></returns>
    public static string Sub(string strTitle, int length)
    {

        Regex regex = new Regex("[\u4e00-\u9fa5]+", RegexOptions.Compiled);
        char[] stringChar = strTitle.ToCharArray();
        string sb = "";
        int nLength = 0;
        for (int i = 0; i < stringChar.Length; i++)
        {
            if (nLength >= length * 2 - 1) //判断是否超过要求长度
            {
                break;
            }
            if (regex.IsMatch((stringChar[i]).ToString()))//如果为汉字
            {
                sb += stringChar[i];
                nLength += 2;
            }
            else if (Char.IsUpper(stringChar[i])) //如果为大写字母
            {
                sb += stringChar[i];
                nLength += 2;
            }
            else//小写字母
            {
                sb += stringChar[i];
                nLength = nLength + 1;
            }
        }
        return sb.ToString();

    }






    #region 取得匹配项内容
    /// <summary>
    /// 取得匹配项内容
    /// </summary>
    /// <param name="_pattern">正则表达式</param>
    /// <param name="_content">匹配内容</param>
    /// <returns></returns>
    public string GetRegstr(string _pattern, string _content)
    {
        try
        {
            Regex re = new Regex(_pattern, RegexOptions.IgnoreCase);
            Match mc = re.Match(_content);
            if (mc.Success)
            {
                return mc.Value;
            }
            return "";
        }
        catch
        { return ""; }

    }

    #endregion



    #region 取的组中的第N项内容
    /// <summary>
    /// 取的组中的第N项内容
    /// </summary>
    /// <param name="_pattern">组正则表达式</param>
    /// <param name="_content">内容</param>
    /// <param name="num">第n项</param>
    /// <returns></returns>
    public string GetOneofGropvalue(string _pattern, string _content, int num)
    {
        try
        {
            Regex re = new Regex(_pattern, RegexOptions.IgnoreCase);
            Match m = re.Match(_content);
            return m.Groups[num].ToString();
        }
        catch
        {
            return "";
        }
    }
    #endregion


}
